package pyrachnid.view;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.SystemColor;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingConstants;

import pyrachnid.ctrl.Simulator;
import pyrachnid.model.ground_model.Wind.Direction;
import pyrachnid.model.scenar_model.Scenario;
import pyrachnid.view.component.RobotTypeComboBoxModel;
import pyrachnid.view.dnd.MapElement;
import pyrachnid.view.listener.DisplayTypeRobotWindowListener;
import pyrachnid.view.listener.LaunchSimuListener;
import pyrachnid.view.listener.MenuItemListener;
import pyrachnid.view.listener.NewMapListener;
import pyrachnid.view.listener.ReinitListener;
import pyrachnid.view.listener.StopSimuListener;
import Decorator.Panneau;


public class MainWindow extends JFrame {
	
	/** Attributes **/
	private static final long serialVersionUID = -8826322472229242223L;

	private Panneau _panneau;
	private Simulator _simulator;
	
	//private DialWin dialWin;
	private StatsWindow _statsWindow;
	private TypeRobotWindow _typeRobotWindow;
	
	private JPanel panel_left;
	private JPanel panel_sim;
	
	private JButton _btn_simLaunch;
	private JButton _btn_simStop;
	private JButton _btn_simReinit;
	private JButton _btn_newMap;
	private JButton _btn_robotManage;
	
	// Wind
	private JSlider _slide_ForceWind;
	private JComboBox _combo_windDirection;
	
	private JComboBox cb_robotTypeChooser;
	
	private JMenuItem mntm_saveSce;
	private JMenuItem mntm_loadSce;
	private JMenuItem mntm_newSce;
	private JMenuItem mntm_quit;
	private JMenuItem mntm_statsView;
	
	MapElement lbl_robotAdd;
	MapElement lbl_fireAdd;
	
	private static final short ROBOT_ELEMENT = 0;
	private static final short FIRE_ELEMENT = 1;
	
	public enum EnumMenuItemName {

		NEW_SCENAR("newSce"),
		LOAD_SCENAR("loadSce"),
		SAVE_SCENAR("saveSce"),
		STATS_VIEW("statsView"),
		QUIT("quit");

		private final String itemName ;
		private EnumMenuItemName(String itemName) {
			this.itemName = itemName;
		}
		public String getItemName() {
			return itemName;
		}	
	}
	
	public MainWindow(Simulator p_sim) {
		_simulator = p_sim;
		initialize();
	}
	
	private void initialize() {
		
		getContentPane().setBackground(Color.WHITE);
		
		setResizable(false);
		setBounds(100, 100, 1200, 800);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		
		/** Menu **/
		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);
		
		// File
		JMenu mn_File = new JMenu("Fichier");
		menuBar.add(mn_File);
		
		mntm_newSce = new JMenuItem("Nouveau sc\u00E9nario");
		mntm_newSce.setName("newSce");
		mn_File.add(mntm_newSce);	
		
		mntm_loadSce = new JMenuItem("Charger sc\u00E9nario");
		mntm_loadSce.setName("loadSce");
		mn_File.add(mntm_loadSce);
		
		mntm_saveSce = new JMenuItem("Sauvegarder sc\u00E9nario");
		mntm_saveSce.setName("saveSce");
		mn_File.add(mntm_saveSce);
		
		mntm_quit = new JMenuItem("Quitter");
		mntm_quit.setName("quit");
		mn_File.add(mntm_quit);
		
		// Statistics
		JMenu mn_stats = new JMenu("Statistiques");
		menuBar.add(mn_stats);
		
		mntm_statsView = new JMenuItem("Afficher statistiques");
		mntm_statsView.setName("statsView");
		mn_stats.add(mntm_statsView);
		
		
		getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.X_AXIS));
		
		panel_left = new JPanel();
		panel_left.setBackground(Color.WHITE);
		panel_left.setAlignmentY(0.0f);
		panel_left.setAlignmentX(0.0f);
		panel_left.setMinimumSize(new Dimension(200, 700));
		panel_left.setMaximumSize(new Dimension(200, 700));
		panel_left.setPreferredSize(new Dimension(200, 700));
		getContentPane().add(panel_left);
		
		/** Simulation Panel **/
		panel_sim = new JPanel();
		panel_left.add(panel_sim);
		
		panel_sim.setLayout(new BoxLayout(panel_sim, BoxLayout.Y_AXIS));
		
		JLabel lbl_sim = new JLabel("Simulation : ");
		lbl_sim.setPreferredSize(new Dimension(200, 30));
		lbl_sim.setMinimumSize(new Dimension(200, 30));
		lbl_sim.setMaximumSize(new Dimension(200, 30));
		lbl_sim.setFont(new Font("Segoe UI", Font.BOLD, 14));
		lbl_sim.setHorizontalAlignment(SwingConstants.CENTER);
		lbl_sim.setVerticalAlignment(SwingConstants.BOTTOM);
		panel_sim.add(lbl_sim);
		
		_btn_simLaunch = new JButton("Lancer");
		_btn_simLaunch.setPreferredSize(new Dimension(200, 40));
		_btn_simLaunch.setMinimumSize(new Dimension(200, 40));
		_btn_simLaunch.setMaximumSize(new Dimension(200, 40));
		panel_sim.add(_btn_simLaunch);
		
		_btn_simStop = new JButton("Arr\u00EAter");
		_btn_simStop.setMinimumSize(new Dimension(200, 40));
		_btn_simStop.setPreferredSize(new Dimension(200, 40));
		panel_sim.add(_btn_simStop);
		_btn_simStop.setMaximumSize(new Dimension(200, 40));
		
		_btn_simReinit = new JButton("R\u00E9inialiser");
		_btn_simReinit.setPreferredSize(new Dimension(200, 40));
		_btn_simReinit.setMinimumSize(new Dimension(200, 40));
		_btn_simReinit.setMaximumSize(new Dimension(200, 40));
		panel_sim.add(_btn_simReinit);
		
		_btn_newMap = new JButton("Charger une nouvelle carte");
		_btn_newMap.setPreferredSize(new Dimension(200, 40));
		_btn_newMap.setMinimumSize(new Dimension(200, 40));
		_btn_newMap.setMaximumSize(new Dimension(200, 40));
		panel_sim.add(_btn_newMap);
		
		JPanel panel_simSpeed = new JPanel();
		panel_simSpeed.setPreferredSize(new Dimension(200, 40));
		panel_simSpeed.setMinimumSize(new Dimension(200, 40));
		panel_simSpeed.setAlignmentY(0.0f);
		panel_simSpeed.setAlignmentX(0.0f);
		panel_simSpeed.setMaximumSize(new Dimension(200, 40));
		panel_sim.add(panel_simSpeed);
		panel_simSpeed.setLayout(new BoxLayout(panel_simSpeed, BoxLayout.X_AXIS));
		
		JLabel lbl_simSpeed = new JLabel("  Vitesse : ");
		panel_simSpeed.add(lbl_simSpeed);
		
		JSlider slider_simSpeed = new JSlider();
		panel_simSpeed.add(slider_simSpeed);
		
		/** Wind Panel **/
		JPanel panel_wind = new JPanel();
		panel_left.add(panel_wind);
		panel_wind.setLayout(new BoxLayout(panel_wind, BoxLayout.Y_AXIS));
		
		JLabel lbl_wind = new JLabel("Vent : ");
		lbl_wind.setVerticalAlignment(SwingConstants.BOTTOM);
		lbl_wind.setPreferredSize(new Dimension(200, 30));
		lbl_wind.setMinimumSize(new Dimension(200, 30));
		lbl_wind.setMaximumSize(new Dimension(200, 30));
		lbl_wind.setHorizontalAlignment(SwingConstants.CENTER);
		lbl_wind.setFont(new Font("Dialog", Font.BOLD, 14));
		panel_wind.add(lbl_wind);
		
		_combo_windDirection = new JComboBox();
		_combo_windDirection.setModel(new DefaultComboBoxModel(new Direction[] {Direction.NORTH, Direction.NORTH_EAST, Direction.EAST, Direction.SOUTH_EAST, Direction.SOUTH, Direction.SOUTH_WEST, Direction.WEST, Direction.NORTH_WEST }));
		_combo_windDirection.setPreferredSize(new Dimension(200, 40));
		_combo_windDirection.setMinimumSize(new Dimension(200, 40));
		_combo_windDirection.setMaximumSize(new Dimension(200, 40));
		_combo_windDirection.setAlignmentX(0.0f);
		panel_wind.add(_combo_windDirection);
		
		JPanel panel_windSpeed = new JPanel();
		panel_windSpeed.setAlignmentX(0.0f);
		panel_windSpeed.setPreferredSize(new Dimension(200, 40));
		panel_windSpeed.setMinimumSize(new Dimension(200, 40));
		panel_windSpeed.setMaximumSize(new Dimension(200, 40));
		panel_wind.add(panel_windSpeed);
		panel_windSpeed.setLayout(new BoxLayout(panel_windSpeed, BoxLayout.X_AXIS));
		
		JLabel label = new JLabel("  Vitesse : ");
		panel_windSpeed.add(label);
		
		_slide_ForceWind = new JSlider();
		panel_windSpeed.add(_slide_ForceWind);
		
		/** Element Panel **/
		JPanel panel_object = new JPanel();
		panel_left.add(panel_object);
		panel_object.setLayout(new BoxLayout(panel_object, BoxLayout.Y_AXIS));
		
		JLabel lbl_object = new JLabel("Element : ");
		lbl_object.setVerticalAlignment(SwingConstants.BOTTOM);
		lbl_object.setPreferredSize(new Dimension(200, 30));
		lbl_object.setMinimumSize(new Dimension(200, 30));
		lbl_object.setMaximumSize(new Dimension(200, 30));
		lbl_object.setHorizontalAlignment(SwingConstants.CENTER);
		lbl_object.setFont(new Font("Segoe UI", Font.BOLD, 14));
		panel_object.add(lbl_object);
		
		lbl_robotAdd = new MapElement("Robot", ROBOT_ELEMENT);
		lbl_robotAdd.setBackground(SystemColor.inactiveCaptionBorder);
		lbl_robotAdd.setForeground(Color.BLACK);
		lbl_robotAdd.setPreferredSize(new Dimension(200, 70));
		lbl_robotAdd.setMinimumSize(new Dimension(200, 70));
		lbl_robotAdd.setMaximumSize(new Dimension(200, 70));
		lbl_robotAdd.setHorizontalAlignment(SwingConstants.LEFT);
		lbl_robotAdd.setIcon(new ImageIcon(MainWindow.class.getResource("/images/main_window/robot.png")));
		panel_object.add(lbl_robotAdd);
		
		lbl_fireAdd = new MapElement("Incendie", FIRE_ELEMENT);
		lbl_fireAdd.setIcon(new ImageIcon(MainWindow.class.getResource("/images/main_window/fire.png")));
		lbl_fireAdd.setPreferredSize(new Dimension(200, 70));
		lbl_fireAdd.setMinimumSize(new Dimension(200, 70));
		lbl_fireAdd.setMaximumSize(new Dimension(200, 70));
		lbl_fireAdd.setHorizontalAlignment(SwingConstants.LEFT);
		lbl_fireAdd.setForeground(Color.BLACK);
		lbl_fireAdd.setBackground(SystemColor.inactiveCaptionBorder);
		panel_object.add(lbl_fireAdd);
		
		/** Manage Robot Panel **/
		JPanel panel_robot = new JPanel();
		panel_left.add(panel_robot);
		panel_robot.setLayout(new BoxLayout(panel_robot, BoxLayout.Y_AXIS));
		
		JLabel lbl_robot = new JLabel("Robot : ");
		lbl_robot.setVerticalAlignment(SwingConstants.BOTTOM);
		lbl_robot.setPreferredSize(new Dimension(200, 30));
		lbl_robot.setMinimumSize(new Dimension(200, 30));
		lbl_robot.setMaximumSize(new Dimension(200, 30));
		lbl_robot.setHorizontalAlignment(SwingConstants.CENTER);
		lbl_robot.setFont(new Font("Dialog", Font.BOLD, 14));
		panel_robot.add(lbl_robot);
		
		cb_robotTypeChooser = new JComboBox();
		cb_robotTypeChooser.setAlignmentX(0.0f);
		cb_robotTypeChooser.setMinimumSize(new Dimension(200, 40));
		cb_robotTypeChooser.setMaximumSize(new Dimension(200, 40));
		cb_robotTypeChooser.setPreferredSize(new Dimension(200, 40));
		panel_robot.add(cb_robotTypeChooser);
		
		_btn_robotManage = new JButton("G\u00E9rer types de robot");
		_btn_robotManage.setPreferredSize(new Dimension(200, 40));
		_btn_robotManage.setMinimumSize(new Dimension(200, 40));
		_btn_robotManage.setMaximumSize(new Dimension(200, 40));
		panel_robot.add(_btn_robotManage);

		createPaneau();
		
		getContentPane().add(_panneau);
		
		/** Listener **/
		
		// Button
		_btn_simLaunch.addActionListener(new LaunchSimuListener(_simulator));
		_btn_simStop.addActionListener(new StopSimuListener(_simulator));
		_btn_robotManage.addActionListener(new DisplayTypeRobotWindowListener(_simulator));
		_btn_newMap.addActionListener(new NewMapListener(_simulator));
		_btn_simReinit.addActionListener(new ReinitListener(_simulator));
		
		// Menu item

		mntm_newSce.addActionListener(new MenuItemListener(_simulator,mntm_newSce.getName()));
		mntm_loadSce.addActionListener(new MenuItemListener(_simulator,mntm_loadSce.getName()));
		mntm_saveSce.addActionListener(new MenuItemListener(_simulator,mntm_saveSce.getName()));
		mntm_quit.addActionListener(new MenuItemListener(_simulator,mntm_quit.getName()));
		mntm_statsView.addActionListener(new MenuItemListener(_simulator,mntm_statsView.getName()));
		
		//init
		
		enableComponents(panel_left, false);
		
		//disable menu items
		mntm_saveSce.setEnabled(false);
		mntm_statsView.setEnabled(false);
		
		//disable drag
		lbl_fireAdd.setEnabled(false);
		lbl_robotAdd.setEnabled(false);
		
		setVisible(true);
	}
	
	private void createPaneau(){
		_panneau = new Panneau();
		_panneau.addComponentListener(new ComponentAdapter() {
			@Override
			public void componentResized(ComponentEvent arg0) {
				_panneau.scaleImage();
			}
		});
		_panneau.setBackground(Color.GRAY);
		//_imagePanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
		_panneau.setLayout(null);
	}
	
	private void enableComponents(Container cont, boolean enable){
		for(Component comp : cont.getComponents()){
			if(comp instanceof Container && comp.getClass() != JButton.class && comp.getClass() != JComboBox.class
					&& comp.getClass() != JSlider.class && comp.getClass() != MapElement.class ){
				enableComponents((Container)comp, enable);
			}
			else
				comp.setEnabled(enable);
		}
	}
	
	public void loadMap(Scenario scenar) {
		removeMap();
		_panneau.loadImage(scenar);
	}
	
	public void removeMap(){
		_panneau.removeMap();
		getContentPane().remove(_panneau);
		createPaneau();
		getContentPane().add(_panneau);
	}
	
	public void loadScenar(Scenario scenar) {
		loadMap(scenar);
		
		//Set model for combobox
		cb_robotTypeChooser.setModel(new RobotTypeComboBoxModel(scenar.getRobotTypeList()));
		
		//set wind values
		valueForceWind(scenar.getWind().getForce());
		valueDirectionWind(scenar.getWind().getDirection());
	
		//enable items
		enableComponents(panel_left, true);
		_btn_simStop.setEnabled(false);
		_btn_simReinit.setEnabled(false);
		mntm_saveSce.setEnabled(true);
		lbl_fireAdd.setEnabled(true);
		this.refreshList();
	}
	
	public void createScenar(){
		enableComponents(panel_left, false);
		removeMap();
		_btn_newMap.setEnabled(true);
		_btn_robotManage.setEnabled(true);
		this.refreshList();
		lbl_fireAdd.setEnabled(false);
	}
	
	/** Manage button display **/

	public void start() {
		this._btn_simLaunch.setEnabled(false);
		this._btn_simStop.setEnabled(true);
		this._btn_newMap.setEnabled(false);
		this._btn_simReinit.setEnabled(false);
		this.mntm_loadSce.setEnabled(false);
		this.mntm_newSce.setEnabled(false);
		this.mntm_saveSce.setEnabled(false);
		this.mntm_statsView.setEnabled(false);
		
		//start annimation
		_panneau.start();
	}

	public void stop() {
		this._btn_simLaunch.setEnabled(true);
		this._btn_simStop.setEnabled(false);
		this._btn_simReinit.setEnabled(true);
		this._btn_newMap.setEnabled(true);
		this.mntm_loadSce.setEnabled(true);
		this.mntm_newSce.setEnabled(true);
		this.mntm_saveSce.setEnabled(true);
		this.mntm_statsView.setEnabled(true);
		

		//stop annimation
		_panneau.stop();
	}

	/** Modal Windows **/

	public void displayStatsWindow() {
		this.setStatsWindow(new StatsWindow(_simulator));
		this._statsWindow.setLocationRelativeTo(this);
	}

	public void displayTypeRobotWindow() {
		this.setTypeRobotWindow(new TypeRobotWindow(_simulator));
		this._typeRobotWindow.setModal(true);
		this._typeRobotWindow.setLocationRelativeTo(this);
		this._typeRobotWindow.setVisible(true);
	}
	
	/** Refresh methods for UI **/
	
	/**
	 * Refresh robot type list
	 */
	public void refreshList() {
		cb_robotTypeChooser.setModel(new RobotTypeComboBoxModel(_simulator.getSenario().getRobotTypeList()));
		int listSize = cb_robotTypeChooser.getModel().getSize();
		
		if (listSize > 0) {
			cb_robotTypeChooser.setEnabled(true);
			cb_robotTypeChooser.setSelectedIndex(0);
			lbl_robotAdd.setEnabled(true);
		} else {
			cb_robotTypeChooser.setEnabled(false);
			lbl_robotAdd.setEnabled(false);
		}
		
		cb_robotTypeChooser.repaint();
		cb_robotTypeChooser.revalidate();
	}
	
	/** Getter/Setter **/
	public Simulator getSimulator() {
		return _simulator;
	}

	private void setStatsWindow(StatsWindow _statsWindow) {
		this._statsWindow = _statsWindow;
	}
	
	public TypeRobotWindow getTypeRobotWindow() {
		return this._typeRobotWindow;
	}

	private void setTypeRobotWindow(TypeRobotWindow _typeRobotWindow) {
		this._typeRobotWindow = _typeRobotWindow;
	}
	
	public JComboBox getCb_robotTypeChooser() {
		return cb_robotTypeChooser;
	}

	public Panneau getPanneau() {
		return _panneau;
	}

	public void valueForceWind(int p_value)
	{
		// Value between 0 and 100
		if(p_value > 100)
		{
			p_value = 100;
		}
		else if(p_value < 0)
		{
			p_value = 0;
		}

		_slide_ForceWind.setValue(p_value);
	}
	
	public void valueDirectionWind(Direction p_value)
	{
		_combo_windDirection.setSelectedItem(p_value);
		_combo_windDirection.repaint();
	}
}
